package com.kangjia.general.dao;

import java.io.Serializable;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.kangjia.general.dao.query.QueryParam;

/**
 * 单表实体实现类,只是用一个service包含一个dao这种模式
 * 
 * @author sunshulin
 *
 * @param <T>
 */
@Repository
public class GeneralAnnotationDao<T> extends AbstractDao {

	/**
	 * 新增/更新
	 * 
	 * @param entity
	 */
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
	public void saveOrUpdate(T entity) {
		Session session = getSession();
		session.saveOrUpdate(entity);
	}

	/**
	 * 查找,没有返回null
	 * 
	 * @param clazz
	 * @param id
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@Transactional(readOnly = true)
	public T get(Class<T> clazz, Serializable id) {
		Session session = getSession();
		return (T) session.get(clazz, id);
	}

	/**
	 * 查找,没有抛异常
	 * 
	 * @param clazz
	 * @param id
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@Transactional(readOnly = true)
	public T load(Class<T> clazz, Serializable id) {
		Session session = getSession();
		return (T) session.load(clazz, id);
	}

	/**
	 * 删除
	 * 
	 * @param clazz
	 * @param id
	 */
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
	public void delete(Class<T> clazz, Serializable id) {
		Session session = getSession();
		T entity = get(clazz, id);
		if (entity != null) {
			session.delete(entity);
		}
	}

	/**
	 * 单表查询
	 * 
	 * @param clazz
	 * @param queryParam
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@Transactional(readOnly = true)
	public List<T> query(Class<T> clazz, QueryParam queryParam) {
		Criteria criteria = getSession().createCriteria(clazz);
		if (queryParam != null) {
			builderCondition(criteria, queryParam.getParams());
			builderOrder(criteria, queryParam.getOrders());
			if (queryParam.isPager()) {
				queryParam.setTotal(getTotal(criteria));
				criteria.setProjection(null);
				criteria.setFirstResult(queryParam.getStart());
				criteria.setMaxResults(queryParam.getLimit());
			}
		}
		return criteria.list();
	}

	/**
	 * 单表统计记录数
	 * 
	 * @param clazz
	 * @param queryParam
	 * @return
	 */
	@Transactional(readOnly = true)
	public Integer count(Class<T> clazz, QueryParam queryParam) {
		Criteria criteria = getSession().createCriteria(clazz);
		if (queryParam != null) {
			builderCondition(criteria, queryParam.getParams());
		}
		return getTotal(criteria);
	}
}
